package rainy.file.synchronization.server;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Base64;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;
import rainy.file.synchronization.config.RainyRunTime;

/**
 * 
 * @author Grom
 *
 */
public class MonitorServerHandler extends SimpleChannelInboundHandler<String> {

	public static ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

	@Override
	public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
		Channel incoming = ctx.channel();
		for (Channel channel : channels) {
			channel.writeAndFlush("[SERVER] - " + incoming.remoteAddress() + " joined\n");
		}
		channels.add(ctx.channel());
	}

	@Override
	public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
		Channel incoming = ctx.channel();
		for (Channel channel : channels) {
			channel.writeAndFlush("[SERVER] - " + incoming.remoteAddress() + " Left\n");
		}
		channels.remove(ctx.channel());
	}

	// 优先级高于messageReceived方法，有了这个方法就会屏蔽messageReceived方法
	// @Override
	// public void channelRead(ChannelHandlerContext ctx, Object msg) throws
	// Exception {
	// System.out.println("channelRead");
	// Channel incoming = ctx.channel();
	// for (Channel channel : channels) {
	// if (channel != incoming){
	// channel.writeAndFlush("[" + incoming.remoteAddress() + "]" + msg + "\n");
	// } else {
	// channel.writeAndFlush("server: " + msg + "\n");
	// }
	// }
	// }

	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		Channel incoming = ctx.channel();
		System.out.println("client " + incoming.remoteAddress() + " online");
	}

	@Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception {
		Channel incoming = ctx.channel();
		System.out.println("client " + incoming.remoteAddress() + " outLine");
	}

	private String folder = RainyRunTime.getPropDefine("rainy.master.target.folder");

	@Override
	protected void messageReceived(ChannelHandlerContext ctx, String msg) throws Exception {
		Channel incoming = ctx.channel();
		if (msg.indexOf("#") > 0) {
			String[] strs = msg.split("#");
			File file = new File(folder, strs[0]);
			System.out.println("[sever] 收到 " + incoming.remoteAddress() + " | " + file);
			if (!file.exists()) {
				synchronized (MonitorServerHandler.class) {
					createFile(file);
				}
			}
			byte[] b = Base64.getDecoder().decode(strs[1]);
			try (FileOutputStream fos = new FileOutputStream(file)) {
				fos.write(b);
			}
		}
	}

	/**
	 * 首先创建所有的parent目录，然后创建文件
	 * 
	 * @param file
	 * @throws IOException
	 */
	private void createFile(File file) throws IOException {
		if (!file.getParentFile().exists()) {
			file.getParentFile().mkdirs();
		}
		if (!file.exists()) {
			file.createNewFile();
		}
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
		Channel incoming = ctx.channel();
		System.out.println("client " + incoming.remoteAddress() + " 异常");
		// 当出现异常就关闭连接
		cause.printStackTrace();
		ctx.close();
	}

}